package com.harmontronics.app.pedestal;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.BarUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.huawei.hms.hmsscankit.OnResultCallback;
import com.huawei.hms.hmsscankit.RemoteView;
import com.huawei.hms.hmsscankit.ScanUtil;
import com.huawei.hms.ml.scan.HmsScan;
import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions;
import com.xiasuhuei321.loadingdialog.view.LoadingDialog;

import java.io.IOException;

public class ScanActivity extends AppCompatActivity {

    public static final String ARGS_SHOW_ALBUM = "show_album";
    public static final String ARGS_SCAN_MODE = "scan_mode";

    private boolean isShowAlbum;
    private int mScanMode;

    private LoadingDialog mLoadingDialog;

    private ActivityResultLauncher<Intent> mSelectImageLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    try {
                        Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), result.getData().getData());
                        if (null == mLoadingDialog) {
                            mLoadingDialog = new LoadingDialog(ActivityUtils.getTopActivity());
                            mLoadingDialog.setLoadingText("解析中")
                                    .setFailedText("未解析到任何内容")
                                    .closeFailedAnim()
                                    .closeSuccessAnim()
                                    .show();
                        }
                        ThreadUtils.getCachedPool().execute(new Runnable() {
                            @Override
                            public void run() {
                                HmsScan[] result = ScanUtil.decodeWithBitmap(ScanActivity.this, bitmap, new HmsScanAnalyzerOptions.Creator()
                                        .setHmsScanTypes(HmsScan.ALL_SCAN_TYPE)
                                        .setPhotoMode(true)
                                        .create());

                                ThreadUtils.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (result != null && result.length > 0 && result[0] != null && !TextUtils.isEmpty(result[0].getOriginalValue())) {
                                            mLoadingDialog.close();
                                            Intent data = new Intent();
                                            data.putExtra("type", result[0].getScanType());
                                            data.putExtra("text", result[0].getOriginalValue());
                                            setResult(RESULT_OK, data);
                                            ScanActivity.this.finish();
                                        } else {
                                            mLoadingDialog.loadFailed();
                                        }
                                    }
                                });
                            }
                        });
                    } catch (IOException e) {
                        e.printStackTrace();
                        mLoadingDialog.loadFailed();
                    }
                }
            });

    //declare RemoteView instance
    private RemoteView remoteView;
    //declare the key ,used to get the value returned from scankit
    public static final String SCAN_RESULT = "scanResult";

    int mScreenWidth;
    int mScreenHeight;
    //The width and height of scan_view_finder is both 240 dp.
    final int SCAN_FRAME_SIZE = 250;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        if (null != getIntent() && null != getIntent().getExtras()) {
            isShowAlbum = getIntent().getBooleanExtra(ARGS_SHOW_ALBUM, true);
            mScanMode = getIntent().getIntExtra(ARGS_SCAN_MODE, 0);
        }
        setContentView(R.layout.activity_scan);

        //1. Obtain the screen density to calculate the viewfinder's rectangle.
        DisplayMetrics dm = getResources().getDisplayMetrics();
        float density = dm.density;
        //2. Obtain the screen size.
        mScreenWidth = getResources().getDisplayMetrics().widthPixels;
        mScreenHeight = getResources().getDisplayMetrics().heightPixels;

        int scanFrameSize = (int) (SCAN_FRAME_SIZE * density);

        //3. Calculate the viewfinder's rectangle, which in the middle of the layout.
        //Set the scanning area. (Optional. Rect can be null. If no settings are specified, it will be located in the middle of the layout.)
        Rect rect = new Rect();
        rect.left = mScreenWidth / 2 - scanFrameSize / 2;
        rect.right = mScreenWidth / 2 + scanFrameSize / 2;
        rect.top = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 120, dm);
        rect.bottom = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 120, dm) + scanFrameSize;

        //initialize RemoteView instance, and set calling back for scanning result
        RemoteView.Builder builder = new RemoteView.Builder()
                .setContext(this)
                .setBoundingBox(rect);
        if (mScanMode == 1) {
            builder.setFormat(HmsScan.QRCODE_SCAN_TYPE, HmsScan.AZTEC_SCAN_TYPE, HmsScan.DATAMATRIX_SCAN_TYPE);
        } else if (mScanMode == 2) {
            builder.setFormat(HmsScan.PDF417_SCAN_TYPE, HmsScan.CODE39_SCAN_TYPE, HmsScan.CODE93_SCAN_TYPE, HmsScan.CODE128_SCAN_TYPE, HmsScan.EAN8_SCAN_TYPE, HmsScan.EAN13_SCAN_TYPE, HmsScan.UPCCODE_E_SCAN_TYPE, HmsScan.UPCCODE_A_SCAN_TYPE);
        } else {
            builder.setFormat(HmsScan.ALL_SCAN_TYPE);
        }
        remoteView = builder.build();
        remoteView.onCreate(savedInstanceState);
        remoteView.setOnResultCallback(new OnResultCallback() {
            @Override
            public void onResult(HmsScan[] result) {
                //judge the result is effective
                if (result != null && result.length > 0 && result[0] != null && !TextUtils.isEmpty(result[0].getOriginalValue())) {
                    Intent data = new Intent();
                    data.putExtra("type", result[0].getScanType());
                    data.putExtra("text", result[0].getOriginalValue());
                    setResult(RESULT_OK, data);
                    ScanActivity.this.finish();
                }
            }
        });

        //add remoteView to framelayout
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        FrameLayout frameLayout = findViewById(R.id.rim);
        frameLayout.addView(remoteView, params);

        View album = findViewById(R.id.album_img);
        album.setVisibility(isShowAlbum ? View.VISIBLE : View.GONE);
        album.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent pickIntent = new Intent(Intent.ACTION_PICK,
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                mSelectImageLauncher.launch(pickIntent);
            }
        });

        findViewById(R.id.back_img).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });

        ImageView flash = findViewById(R.id.ivFlashlight);
        flash.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                remoteView.switchLight();
                flash.setImageResource(remoteView.getLightStatus() ? R.mipmap.ic_scan_light_on : R.mipmap.ic_scan_light_off);
            }
        });
    }

    //manage remoteView lifecycle
    @Override
    protected void onStart() {
        super.onStart();
        remoteView.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        remoteView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        remoteView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        remoteView.onDestroy();
    }

    @Override
    protected void onStop() {
        super.onStop();
        remoteView.onStop();
    }
}
